package com.myapi.project.service.impl;


import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myapi.myapiconmon.model.entity.UserInterfaceInfo;
import com.myapi.project.common.ErrorCode;
import com.myapi.project.exception.BusinessException;
import com.myapi.project.mapper.UserInterfaceInfoMapper;
import com.myapi.project.service.UserInterfaceInfoService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

/**
* @author 86136
* @description 针对表【user_interface_info(用户调用接口关系)】的数据库操作Service实现
* @createDate 2023-03-19 15:35:05
*/
@Slf4j
@Service
public class UserInterfaceInfoServiceImpl extends ServiceImpl<UserInterfaceInfoMapper, UserInterfaceInfo>
    implements UserInterfaceInfoService {

    @Resource
    private RedissonClient redisson;

    @Override
    public void validUserInterfaceInfo(UserInterfaceInfo userInterfaceInfo, boolean add) {
        if (userInterfaceInfo == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        // 创建时，所有参数必须非空
        if (add) {
            if (userInterfaceInfo.getInterfaceInfoId() <= 0 || userInterfaceInfo.getUserId() <= 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "接口或用户不存在");
            }
        }
        if (userInterfaceInfo.getLeftNum() < 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "剩余次数不能小于 0");
        }
    }

    @Override
    public boolean invokeCount(long interfaceInfoId, long userId) {
        // 判断
        if (interfaceInfoId <= 0 || userId <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //使用分布式锁
        String lockKey = UUID.randomUUID().toString();
        RLock lock = redisson.getLock(lockKey);
        boolean update = false;
        try {
            lock.lock(); //加锁
            log.info("加锁");
            //synchronized (this) {
                UpdateWrapper<UserInterfaceInfo> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("interfaceInfoId", interfaceInfoId);
                updateWrapper.eq("userId", userId);
                updateWrapper.gt("leftNum", 0);
                System.out.println("id: " + userId + "  接口id: " + interfaceInfoId);
                updateWrapper.setSql("leftNum = leftNum - 1, totalNum = totalNum + 1");
                update = this.update(updateWrapper);
                System.out.println("扣减结果"+update);
            //}
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();    //删除锁
            log.info("释放锁");
        }
        return update;
    }
}




